package com.hzsk.lisence.service.impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.hzsk.lisence.config.myexception.BaseException;
import com.hzsk.lisence.entity.*;
import com.hzsk.lisence.entity.query.EmFileQuery;
import com.hzsk.lisence.entity.query.IDCInfoQuery;
import com.hzsk.lisence.enums.ChannelEnum;
import com.hzsk.lisence.enums.FunctionItemEnum;
import com.hzsk.lisence.enums.ProdTypeEnum;
import com.hzsk.lisence.mapper.EmFileMapper;
import com.hzsk.lisence.service.*;
import com.sun.jna.Memory;
import com.sun.jna.Pointer;
import jcifs.smb.SmbFile;
import jcifs.smb.SmbFileOutputStream;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.util.ObjectUtils;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.*;
import java.net.MalformedURLException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Description :
 * @Date : 2024/8/29
 * @Author : ChenJin
 * @Version : v1.0.0
 **/
@Service
public class EmFileServiceImpl implements EmFileService {
    
    @Value("${share-directory.host}")
    private String shareHost;

    @Value("${share-directory.username}")
    private String shareUsername;

    @Value("${share-directory.password}")
    private String sharePassword;

    @Value("${share-directory.base-path}")
    private String shareBasePath;
    
    @Resource
    private IDCService idcService;
    
    @Resource
    private EmRelationBindService emRelationBindService;
    
    @Resource
    private AsyncTaskService asyncTaskService;
    
    @Resource
    private EmFileMapper emFileMapper;

    @Override
    public void uploadFile(MultipartFile file,String type,String prodType, Integer userId,String description) throws BaseException, IOException {
        if (file.isEmpty()) {
            throw new BaseException("上传文件为空，请重选选择文件");
        }
        if(emFileMapper.selectEmFileByFileName(file.getOriginalFilename())>0){
            throw new BaseException("文件名已存在");
        }
        String fileName = file.getOriginalFilename();
        String filePath = type;
        EmFileEntity emFileEntity = new EmFileEntity();
        emFileEntity.setFileType(type);
        emFileEntity.setProdType(prodType);
        emFileEntity.setFileName(fileName);
        emFileEntity.setFilePath(shareHost + shareBasePath + filePath + "/" + fileName);
        emFileEntity.setDescription(description);
        emFileEntity.setCreator(userId);
        emFileMapper.insertDeviceRelationEntity(emFileEntity);
        asyncTaskService.asyncUploadFile((FileInputStream) file.getInputStream(),filePath,fileName);
    }

    @Override
    public List<EmFileEntity> getFileList(EmFileQuery emFileQuery) {
        return emFileMapper.selectEmFileList(emFileQuery);  
    }

    @Override
    public PageInfo<EmFileEntity> getFilePage(EmFileQuery emFileQuery) {
        PageHelper.startPage(emFileQuery.getPageNum(), emFileQuery.getPageSize());
        List<EmFileEntity> emFileEntityList = emFileMapper.selectEmFileList(emFileQuery);
        return new PageInfo<>(emFileEntityList);
    }

    @Override
    public void deleteById(Integer id) throws BaseException {
        EmFileEntity emFileEntity = emFileMapper.selectEmFileById(id);
        if (ObjectUtils.isEmpty(emFileEntity)){
            throw new BaseException("文件不存在!");
        }
//        String filePath = emFileEntity.getFilePath();
//        asyncTaskService.asyncDeleteFile(filePath);
        emFileMapper.deleteById(id);
    }


    @Override
    public Map getEmpowerFile(IDCInfoQuery idcInfoQuery) throws BaseException {
        
        Map<Object, Object> result = new HashMap<>();
        String sharePath = shareHost+shareBasePath;
        result.put("sharePath","//"+sharePath);
        try {
            String deviceId = idcInfoQuery.getIdcDeviceId();
            if (StringUtils.isEmpty(deviceId)){
                throw new BaseException("设备ID为空");
            }
            IDCEntity idc = idcService.getIdcEntityByIdcDeviceId(deviceId);
            if (ObjectUtils.isEmpty(idc)){
                throw new BaseException("IDC设备不存在");
            }
            String idcChipId = idc.getIdcChipId();
            //查询绑定关系
            EmDeviceRelationEntity deviceRelationByIdcProductCode = emRelationBindService.getDeviceRelationByIdcProductCode(idcChipId);
            if (ObjectUtils.isEmpty(deviceRelationByIdcProductCode)){
                throw new BaseException("产品绑定关系不存在");
            }
            deviceRelationByIdcProductCode.setIdcDeviceId(deviceId);

            LocalDate currentDate = LocalDate.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
            String dateStart = currentDate.format(formatter);//授权开始时间
            String dateEnd = "20990101";//授权截止时间
            //生成授权清单
            String functionListFilePath = this.generateFunctionList(deviceRelationByIdcProductCode,dateStart,dateEnd);
            result.put("functionListFilePath",functionListFilePath.substring(sharePath.length()));
            //生成授权文件
            String empowerFilePath = this.generateEmpowerFile(deviceRelationByIdcProductCode,dateStart,dateEnd);
            result.put("empowerFilePath",empowerFilePath.substring(sharePath.length()));
            //获取OS软件
            Integer osFileId = deviceRelationByIdcProductCode.getOsId();
            EmFileEntity osFile = emFileMapper.selectEmFileById(osFileId);
            String osFilePath = osFile.getFilePath();
            result.put("osFilePath",osFilePath.substring(sharePath.length()));
            //获取软件包
            Integer softwareFileId = deviceRelationByIdcProductCode.getSoftwareId();
            EmFileEntity softwareFile = emFileMapper.selectEmFileById(softwareFileId);
            String softwareFilePath = softwareFile.getFilePath();
            result.put("softwareFilePath",softwareFilePath.substring(sharePath.length()));
        }catch (Exception e){
            throw new BaseException(e.getMessage());
        }
        return result;
    }
    
    private String generateFunctionList(EmDeviceRelationEntity deviceRelationEntity,String dateStart,String dateEnd) throws BaseException {
        // 获取当前工作目录的绝对路径（注意：这可能不是应用的jar包所在的目录
        SmbFileOutputStream smbOutputStream = null;
        OutputStreamWriter writer = null;
        String filePath = null;
        try {
            String remoteUrl =  "smb://" + shareUsername + ":" + sharePassword + "@" + shareHost + shareBasePath;
            SmbFile smbFileFolder = new SmbFile(remoteUrl + deviceRelationEntity.getIdcProductCode());
            if (!smbFileFolder.exists()){
                smbFileFolder.mkdir();
            }
            String fileName = "falist.txt";
            SmbFile smbFile = new SmbFile(remoteUrl + deviceRelationEntity.getIdcProductCode()+"/"+fileName);
            smbOutputStream = new SmbFileOutputStream(smbFile);
           // 写入内容
            writer = new OutputStreamWriter(smbOutputStream, Charset.forName("GB2312"));
            writer.write("信息项:信息内容");
            writer.write("\n");
            writer.write(("NC单元标识:"+deviceRelationEntity.getProductCode()));
            writer.write("\n");
            writer.write("授权开始日期:"+dateStart); // 或 "软件期限:2099/1/1" 如果你想设置为永久
            writer.write("\n");
            writer.write("授权截止日期:"+dateEnd); // 或 "软件期限:2099/1/1" 如果你想设置为永久
            writer.write("\n");
            writer.write(("产品类型:"+ ProdTypeEnum.getNameByCode(deviceRelationEntity.getProdType())));
            writer.write("\n");
            writer.write(("功能项1:"+ ChannelEnum.getNameByCode(deviceRelationEntity.getChannelNum())));
            String functions = deviceRelationEntity.getFunctions();
            if (StringUtils.isNotEmpty(functions)){
                writer.write("\n");
                String[] functionArr = functions.split(",");
                for (int i=0;i<functionArr.length;i++){
                    boolean isLastLine = (i == functionArr.length - 1);
                    writer.write(("功能项"+(i+2)+":"+ FunctionItemEnum.getNameByCode(functionArr[i])));
                    if (!isLastLine){
                        writer.write("\n");
                    }
                }
            }
            writer.flush();
            filePath = shareHost + shareBasePath + deviceRelationEntity.getIdcProductCode() + "/" +fileName;
            System.out.println("授权清单文件已保存到SMB共享文件夹");

        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("无法连接到SMB共享文件夹或保存文件");
        } finally {
            if (writer!=null){
                try {
                    smbOutputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return filePath;
    }
    
    private String generateEmpowerFile(EmDeviceRelationEntity emDeviceRelationEntity,String dateStart,String dateEnd) throws BaseException{
        
        SmbFileOutputStream smbOutputStream = null;
        String filePath = null;
        try {
            FA_DescriptionInfo.ByValue fa_descriptionInfo = new FA_DescriptionInfo.ByValue();
            String prjName = emDeviceRelationEntity.getIdcProductCode();
            for (int i=0;i<prjName.length();i++){
                fa_descriptionInfo.prjName[i] = (byte) prjName.charAt(i);
            }
            String prjInfo = "licensing management project";
            for (int i=0;i<prjInfo.length();i++){
                fa_descriptionInfo.prjInfo[i] = (byte) prjInfo.charAt(i);
            }
            FA_VerifyInfo.ByValue fa_verifyInfo = new FA_VerifyInfo.ByValue();
            String certificator = "hzsk";
            for (int i=0;i<certificator.length();i++){
                fa_verifyInfo.certificator[i] = (byte) certificator.charAt(i);
            }
            String userName = "user1";
            for (int i=0;i<userName.length();i++){
                fa_verifyInfo.userName[i] = (byte) userName.charAt(i);
            }
            String hardwareInfo = emDeviceRelationEntity.getIdcDeviceId();
            for (int i=0;i<hardwareInfo.length();i++){
                fa_verifyInfo.hardwareInfo[i] = (byte) hardwareInfo.charAt(i);
            }
            FA_FuncItemInfo.ByValue fa_funcItemInfo = new FA_FuncItemInfo.ByValue();
            String ncProductCode = emDeviceRelationEntity.getProductCode();
            for (int i=0;i<ncProductCode.length();i++){
                fa_funcItemInfo.FuncItemArr[i] = (byte) ncProductCode.charAt(i);
            }
            for (int i=0;i<dateStart.length();i++){
                fa_funcItemInfo.FuncItemArr[33 +i] = (byte) dateStart.charAt(i);
            }
            for (int i=0;i<dateEnd.length();i++){
                fa_funcItemInfo.FuncItemArr[33*2+i] = (byte) dateEnd.charAt(i);
            }
            String prodType = emDeviceRelationEntity.getProdType();
            for (int i=0;i<prodType.length();i++){
                fa_funcItemInfo.FuncItemArr[33*3+i] = (byte) prodType.charAt(i);
            }
            String channelNum = emDeviceRelationEntity.getChannelNum();
            for (int i=0;i<channelNum.length();i++){
                fa_funcItemInfo.FuncItemArr[33*4+i] = (byte) channelNum.charAt(i);
            }
            int count = 5;
            String functions = emDeviceRelationEntity.getFunctions();
            if (StringUtils.isNotEmpty(functions)){
                String[] functionArr = functions.split(",");
                count = count + functionArr.length;
                for (int i=0;i<functionArr.length;i++){
                    for (int j=0;j<functionArr[i].length();j++){
                        fa_funcItemInfo.FuncItemArr[33*(i+5)+j] = (byte) functionArr[i].charAt(j);
                    }
                }
            }
            fa_funcItemInfo.funcItemCnt = count;
            String filepath_s = "dftfile.fa";//当前目录下生成，文件名为dftfile.fa
            Pointer bufferpointer = new Memory(filepath_s.length()+ 1); // WARNING: assumes ascii-only string
            bufferpointer.setString( 0, filepath_s);
            int result = EmAuthFileService.emAuthFileService.FA_EncryptedFuncAuthInfo(fa_descriptionInfo, fa_verifyInfo, fa_funcItemInfo, bufferpointer);
            if (0 != result){
                System.out.println(result);
                throw new BaseException("生成授权文件失败");
            }
            Path path = Paths.get(filepath_s);
            String content = new String(Files.readAllBytes(path));
            if (StringUtils.isEmpty(content)){
                throw new BaseException("生成授权文件失败");
            }
            String remoteUrl =  "smb://" + shareUsername + ":" + sharePassword + "@" + shareHost + shareBasePath;
            SmbFile smbFileFolder = new SmbFile(remoteUrl + emDeviceRelationEntity.getIdcProductCode());
            if (!smbFileFolder.exists()){
                smbFileFolder.mkdir();
            }
            String fileName = "dftfile.fa";
            SmbFile smbFile = new SmbFile(remoteUrl + emDeviceRelationEntity.getIdcProductCode()+"/"+fileName); // 如果使用NtlmPasswordAuthentication，则可能需要不同的构造函数或设置
            smbOutputStream = new SmbFileOutputStream(smbFile);
            // 写入内容  
            smbOutputStream.write(content.getBytes());
            smbOutputStream.flush();
            filePath = shareHost + shareBasePath + emDeviceRelationEntity.getIdcProductCode() + "/" +fileName;
            System.out.println("授权文件已保存到SMB共享文件夹");

        } catch (IOException e) {
            e.printStackTrace();
            System.out.println("无法连接到SMB共享文件夹或保存文件");
        } finally {
            if (smbOutputStream!=null){
                try {
                    smbOutputStream.close();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
        }
        return filePath;
    }

    public static void main(String[] args) throws IOException {
        SmbFile smbFile = new SmbFile("smb://empower:Hzsk2024@10.1.1.113/EmpowerShareFile/falist.txt");
        InputStream in = smbFile.getInputStream();
        FileOutputStream out = new FileOutputStream("D:/falist.txt");  // 保存到本地的文件路径
        byte[] buffer = new byte[8192];
        int len;
        while ((len = in.read(buffer)) != -1) {
            out.write(buffer, 0, len);
        }
        out.close();
        in.close();
    }

}
